package pikes.peak;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import org.junit.Assert;
import org.junit.Test;
import pikes.core.Printable;
import pikes.ecma.EcmaSyntaxVisitingException;
import pikes.ecma.PrintableSourceElement;
import pikes.ecma.SourceElement;
import pikes.ecma.SourceElements;
import pikes.ecma.SyntaxTreeVisitor;
import pikes.html.xhtml.Inline;
import pikes.html.xhtml.Script;
import pikes.peak.EcmaScriptCode;
import pikes.peak.ScriptFormattingConfiguration;
import pikes.peak.test.AssertHtml;
import pikes.peak.test.PikesPeakComponentTestCase;
import pikes.xml.XMLTag;
import org.springframework.web.servlet.support.RequestContext;

public class ClientSideScriptTestCase extends PikesPeakComponentTestCase {

	@Test
	public void emptyScript() throws Exception {
		EcmaScriptCode cs = new EcmaScriptCode();

		Script expected = new Script("text/javascript");
		expected.setCode(new Printable() {

			public void print(Appendable arg0) throws IOException {

			}

		});
		Inline actual = cs.createHtml(new HashMap(), pikesPeakRequest.getRequestContext());
		AssertHtml.assertEquals(expected, actual);
	}

	@Test
	public void createNullScript() throws Exception {
		EcmaScriptCode cs = new EcmaScriptCode(new SourceElements());

		Script expected = new Script("text/javascript");
		expected.setCode(new Printable() {

			public void print(Appendable arg0) throws IOException {

			}

		});
		Inline actual = cs.createHtml(new HashMap(), pikesPeakRequest.getRequestContext());
		AssertHtml.assertEquals(expected, actual);
	}

	@Test
	public void simpleScript() throws Exception {
		SourceElements sourceElements = new SourceElements();
		sourceElements.add(new PrintableSourceElement() {

			public void visit(SyntaxTreeVisitor syntaxTreeVisitor) throws EcmaSyntaxVisitingException {
				syntaxTreeVisitor.identifier("id");
			}

		});

		EcmaScriptCode cs = new EcmaScriptCode(sourceElements);

		Script expected = new Script("text/javascript");
		StringBuilder code = new StringBuilder();
		code.append("id");
		expected.setCode(code.toString());

		Inline actual = cs.createHtml(new HashMap(), pikesPeakRequest.getRequestContext());
		AssertHtml.assertEquals(expected, actual);
	}

	@Test
	public void simpleScript2() throws Exception {
		SourceElements sourceElements = new SourceElements();
		sourceElements.add(new PrintableSourceElement() {

			public void visit(SyntaxTreeVisitor syntaxTreeVisitor) throws EcmaSyntaxVisitingException {
				syntaxTreeVisitor.identifier("id");
			}

		});

		EcmaScriptCode cs = new EcmaScriptCode(sourceElements);
		cs.setScriptFormattingConfiguration(new ScriptFormattingConfiguration() {

			public SyntaxTreeVisitor createScriptSyntaxVisitor(Appendable appendable) {
				return null;
			}
		});

		Script expected = new Script("text/javascript");
		StringBuilder code = new StringBuilder();
		code.append("id");
		expected.setCode(code.toString());

		Inline actual = cs.createHtml(new HashMap(), pikesPeakRequest.getRequestContext());
		AssertHtml.assertEquals(expected, actual);
	}

	@Test
	public void simpleScript3() throws Exception {
		final MockSyntaxTreeVisitor mocksyntaxtree = new MockSyntaxTreeVisitor();
		final MockSourceElement mockSourceElement = new MockSourceElement();
		final MockScriptFormattingConfiguration mockConfig = new MockScriptFormattingConfiguration();
		mockConfig.syntaxTreeVisitor = mocksyntaxtree;

		SourceElements sourceElements = new SourceElements();
		sourceElements.add(mockSourceElement);

		EcmaScriptCode cs = new EcmaScriptCode(sourceElements);
		cs.setScriptFormattingConfiguration(mockConfig);

		Inline actual = cs.createHtml(new HashMap(), pikesPeakRequest.getRequestContext());

		XMLTag tag = new XMLTag("sample");
		actual.decorateTag(tag);

		tag.print(new StringBuilder());

		Assert.assertSame(mocksyntaxtree, mockSourceElement.syntaxTreeVisitor);

	}
}

class MockScriptFormattingConfiguration implements ScriptFormattingConfiguration {

	public SyntaxTreeVisitor syntaxTreeVisitor = null;

	public Appendable appendable = null;

	public SyntaxTreeVisitor createScriptSyntaxVisitor(Appendable appendable) {
		this.appendable = appendable;
		return syntaxTreeVisitor;
	}

}

class MockSourceElement implements SourceElement {

	public SyntaxTreeVisitor syntaxTreeVisitor = null;

	public void visit(SyntaxTreeVisitor syntaxTreeVisitor) throws EcmaSyntaxVisitingException {
		this.syntaxTreeVisitor = syntaxTreeVisitor;
	}

	public void print(Appendable arg0) throws IOException {
		// TODO Auto-generated method stub

	}

}

class MockSyntaxTreeVisitor implements SyntaxTreeVisitor {

	public CharSequence id = null;

	public void Do() throws EcmaSyntaxVisitingException {
		// TODO Auto-generated method stub

	}

	public void Else() throws EcmaSyntaxVisitingException {
		// TODO Auto-generated method stub

	}

	public void Function() throws EcmaSyntaxVisitingException {
		// TODO Auto-generated method stub

	}

	public void If() throws EcmaSyntaxVisitingException {
		// TODO Auto-generated method stub

	}

	public void New() throws EcmaSyntaxVisitingException {
		// TODO Auto-generated method stub

	}

	public void Return() throws EcmaSyntaxVisitingException {
		// TODO Auto-generated method stub

	}

	public void While() throws EcmaSyntaxVisitingException {
		// TODO Auto-generated method stub

	}

	public void closeCurlyBrace() throws EcmaSyntaxVisitingException {
		// TODO Auto-generated method stub

	}

	public void afterParameterList() throws EcmaSyntaxVisitingException {
		// TODO Auto-generated method stub

	}

	public void openCurlyBrace() throws EcmaSyntaxVisitingException {
		// TODO Auto-generated method stub

	}

	public void beforeParameterList() throws EcmaSyntaxVisitingException {
		// TODO Auto-generated method stub

	}

	public void beforeVariableDeclarations() throws EcmaSyntaxVisitingException {
		// TODO Auto-generated method stub

	}

	public void binaryOperator(CharSequence operator) throws EcmaSyntaxVisitingException {
		// TODO Auto-generated method stub

	}

	public void colon() throws EcmaSyntaxVisitingException {
		// TODO Auto-generated method stub

	}

	public void comma() throws EcmaSyntaxVisitingException {
		// TODO Auto-generated method stub

	}

	public void dotOperator() throws EcmaSyntaxVisitingException {
		// TODO Auto-generated method stub

	}

	public void endOfStatement() throws EcmaSyntaxVisitingException {
		// TODO Auto-generated method stub

	}

	public void equalSign() throws EcmaSyntaxVisitingException {
		// TODO Auto-generated method stub

	}

	public void identifier(CharSequence text) throws EcmaSyntaxVisitingException {
		this.id = text;
	}

	public void questionMark() throws EcmaSyntaxVisitingException {
		// TODO Auto-generated method stub

	}

	public void stringQuote() throws EcmaSyntaxVisitingException {
		// TODO Auto-generated method stub

	}

	public void visitSourceElement(SourceElement sourceElement) throws EcmaSyntaxVisitingException {
		// TODO Auto-generated method stub

	}

	public void whiteSpace() throws EcmaSyntaxVisitingException {
		// TODO Auto-generated method stub

	}

	public void closeSquaredBrace() throws EcmaSyntaxVisitingException {
		// TODO Auto-generated method stub

	}

	public void openSquaredBrace() throws EcmaSyntaxVisitingException {
		// TODO Auto-generated method stub

	}

	public void beforeSourceElement() throws EcmaSyntaxVisitingException {
		// TODO Auto-generated method stub

	}

	public void identifier(Printable text) throws EcmaSyntaxVisitingException {
		// TODO Auto-generated method stub

	}

}